package persistence;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import model.Board;

/**
 * Base de conhecimento.
 * 
 * Controla o acesso ao banco de dados.
 */
public class KnowBase {
	
	/**
	 * Conexão com o banco de dados.
	 */
	private Connection con = null;
	
	/**
	 * O construtor carrega o driver do banco de dados de tenta estabelecer uma
	 * conexão.
	 */
	public KnowBase() {
		try {
			Class.forName("org.hsqldb.jdbc.JDBCDriver");
			con = DriverManager.getConnection("jdbc:hsqldb:file:db/knowbase", "iaplayer", "expert");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Recupera a pontuação para a configuração atual do tabuleiro.
	 */
	public int getScore(Board board) {
		
		/* Se essa configuração já estiver no banco, recupera com select. */
		PreparedStatement select;
		try {
			select = con.prepareStatement("SELECT (score) FROM move WHERE state = ?");
			select.setString(1, board.toString());
			ResultSet rs = select.executeQuery();
			if (rs.next()) {
				return rs.getInt("score");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		/* Se não existia essa configuração no banco, insere ela com pontuação 1. */
		PreparedStatement insert;
		try {
			insert = con.prepareStatement("INSERT INTO move VALUES (?, 1)");
			insert.setString(1, board.toString());
			insert.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return 1;
	}

	/**
	 * Salva a nova pontuação para essas jogadas.
	 * 
	 * @param state A string representando o estado do tabuleiro (board.toString()).
	 */
	public void saveScore(String state, int score) {
		try {
			PreparedStatement update = con.prepareStatement("UPDATE move SET score=? WHERE state=?");
			update.setInt(1, score);
			update.setString(2, state);
			update.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void finalize() throws Throwable {
		con.close();
		super.finalize();
	}

}
